﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TinyCinema.Data;
using System.Windows.Input;
using System.Windows;
using System.Windows.Controls;
using System.Collections.ObjectModel;
namespace TinyCinema.Bussiness.Customer 
{
        public class Customer : DependencyObject
        {
            public static DependencyProperty lstCustomerProperty = DependencyProperty.Register("lstCustomer", typeof(ObservableCollection<Data.Customer>), typeof(Customer));
            public ObservableCollection<Data.Customer> lstCustomer
            {
                get { return (ObservableCollection<Data.Customer>)GetValue(lstCustomerProperty); }
                set { SetValue(lstCustomerProperty, value); }
            }
            public static DependencyProperty lstTicketOrderProperty = DependencyProperty.Register("lstTicketOrder", typeof(ObservableCollection<Data.TicketOrder>), typeof(Customer));
            public ObservableCollection<Data.TicketOrder> lstTicketOrder
            {
                get { return (ObservableCollection<Data.TicketOrder>)GetValue(lstTicketOrderProperty); }
                set { SetValue(lstTicketOrderProperty, value); }
            }
            public static DependencyProperty lstBookedTicketProperty = DependencyProperty.Register("lstBookedTicket", typeof(ObservableCollection<Data.BookedTicket>), typeof(Customer));
            public ObservableCollection<Data.BookedTicket> lstBookedTicket
            {
                get { return (ObservableCollection<Data.BookedTicket>)GetValue(lstBookedTicketProperty); }
                set { SetValue(lstBookedTicketProperty, value); }
            }
            public static DependencyProperty lstMenuOrderProperty = DependencyProperty.Register("lstMenuOrder", typeof(ObservableCollection<Data.MenuOrder>), typeof(Customer));
            public ObservableCollection<Data.MenuOrder> lstMenuOrder
            {
                get { return (ObservableCollection<Data.MenuOrder>)GetValue(lstMenuOrderProperty); }
                set { SetValue(lstMenuOrderProperty, value); }
            }
            public static DependencyProperty IsEditableProperty = DependencyProperty.Register("IsEditable", typeof(bool), typeof(Customer));
            public bool IsEditable
            {
                get { return (bool)GetValue(IsEditableProperty); }
                set
                {
                    SetValue(IsEditableProperty, value);
                }
            }
            public static DependencyProperty CurrentViewProperty = DependencyProperty.Register("CurrentView", typeof(Data.Customer), typeof(Customer));
            public Data.Customer CurrentView
            {
                get { return (Data.Customer)GetValue(CurrentViewProperty); }
                set
                {
                    SetValue(CurrentViewProperty, value);
                    if (value == null) return;
                    if ((value as Data.Customer).ID == null) IsEditable = true;
                    else IsEditable = false;
                }
            }
            public static DependencyProperty IsViewModeEnableProperty = DependencyProperty.Register("IsViewModeEnable", typeof(bool), typeof(Customer));
            public bool IsViewModeEnable
            {
                get { return (bool)GetValue(IsViewModeEnableProperty); }
                set
                {
                    SetValue(IsViewModeEnableProperty, value);
                }
            }
            public static DependencyProperty strSearchProperty = DependencyProperty.Register("strSearch", typeof(string), typeof(Customer));
            public string strSearch
            {
                get { return (string)GetValue(strSearchProperty); }
                set
                {
                    SetValue(strSearchProperty, value);
                }
            }
            public static DependencyProperty IsSearchingProperty = DependencyProperty.Register("IsSearching", typeof(bool), typeof(Customer));
            public bool IsSearching
            {
                get { return (bool)GetValue(IsSearchingProperty); }
                set
                {
                    SetValue(IsSearchingProperty, value);
                }
            }
            public static DependencyProperty SearchFilterProperty = DependencyProperty.Register("SearchFilter", typeof(ObservableCollection<String>), typeof(Customer));
            public ObservableCollection<String> SearchFilter
            {
                get { return (ObservableCollection<String>)GetValue(SearchFilterProperty); }
                set { SetValue(SearchFilterProperty, value); }
            }
            public static DependencyProperty SearchFilterIndexProperty = DependencyProperty.Register("SearchFilterIndex", typeof(int), typeof(Customer));
            public int SearchFilterIndex
            {
                get { return (int)GetValue(SearchFilterIndexProperty); }
                set { SetValue(SearchFilterIndexProperty, value); }
            }
            public static DependencyProperty CurrentViewIndexProperty = DependencyProperty.Register("CurrentViewIndex", typeof(int), typeof(Customer));
            public int CurrentViewIndex
            {
                get { return (int)GetValue(CurrentViewIndexProperty); }
                set
                {
                    if (value < 1 || value > lstCustomer.Count) return;
                    try { CurrentView = lstCustomer[value - 1]; }
                    catch { return; }
                    SetValue(CurrentViewIndexProperty, value);
                }
            }
            public static DependencyProperty FromDateProperty = DependencyProperty.Register("FromDate", typeof(DateTime), typeof(Customer));
            public DateTime FromDate
            {
                get { return (DateTime)GetValue(FromDateProperty); }
                set { SetValue(FromDateProperty, value); }
            }
            public static DependencyProperty ToDateProperty = DependencyProperty.Register("ToDate", typeof(DateTime), typeof(Customer));
            public DateTime ToDate
            {
                get { return (DateTime)GetValue(ToDateProperty); }
                set { SetValue(ToDateProperty, value); }
            }
            public static DependencyProperty IsTradeLogViewingProperty = DependencyProperty.Register("IsTradeLogViewing", typeof(bool), typeof(Customer));
            public bool IsTradeLogViewing
            {
                get { return (bool)GetValue(IsTradeLogViewingProperty); }
                set { SetValue(IsTradeLogViewingProperty, value); }
            }
            public ICommand ChooseCustomerCommand { get; set; }
            public ICommand CreateCommand { get; set; }
            public ICommand EditCommand { get; set; }
            public ICommand SaveCommand { get; set; }
            public ICommand BackCommand { get; set; }
            public ICommand DeleteCommand { get; set; }
            public ICommand PreviousCommand { get; set; }
            public ICommand NextCommand { get; set; }
            public ICommand GoToPageCommand { get; set; }
            public ICommand SearchCommand { get; set; }
            public ICommand SearchCancelCommand { get; set; }
            public ICommand FilterCommand { get; set; }
            public ICommand ViewAllCommand { get; set; }
            public ICommand SetCustomerCommand { get; set; }
            public ICommand ResetPasswordCommand { get; set; }
            public ICommand BackToFormViewCommand { get; set; }
            bool IsCreating;
            public Messenger Messenger { get; set; }
            public void NewCustomer()
            {
                CurrentView = new Data.Customer();
            }
            public void LoadDateTime()
            {
                string GetFromDateFromTicketOrder = "select " + TicketOrderTable.OrderDate + " from " + Tables.TicketOrder + " where " + TicketOrderTable.CustomerID + "= '" + CurrentView.ID + "' order by " + TicketOrderTable.OrderDate;
                string GetFromDateFromBookedTicket = "select " + BookedTicketTable.BookedDate + " from " + Tables.BookedTicket + " where " + BookedTicketTable.CustomerID + "= '" + CurrentView.ID + "' order by " + BookedTicketTable.BookedDate;
                string GetFromDateFromMenuOrder = "select " + MenuOrderTable.OrderTime + " from " + Tables.MenuOrder + " where " + MenuOrderTable.CustomerID + "= '" + CurrentView.ID + "' order by " + MenuOrderTable.OrderTime;
                var x = Data.TicketOrder.Excute(GetFromDateFromTicketOrder);
                var y = Data.BookedTicket.Excute(GetFromDateFromBookedTicket);
                var z = Data.MenuOrder.Excute(GetFromDateFromMenuOrder);
                if (x.Rows.Count == 0)
                {
                    if (y.Rows.Count != 0 && z.Rows.Count == 0)
                        FromDate = (DateTime)y.Rows[0][0];
                    else
                        if (y.Rows.Count == 0 && z.Rows.Count != 0)
                            FromDate = (DateTime)z.Rows[0][0];
                        else if (y.Rows.Count != 0 && z.Rows.Count != 0)
                            FromDate = MinDateTime((DateTime)y.Rows[0][0], (DateTime)z.Rows[0][0]);
                        else FromDate = DateTime.Now;
                }
                else
                {
                    if (y.Rows.Count == 0 && z.Rows.Count != 0)
                        FromDate = MinDateTime((DateTime)z.Rows[0][0], (DateTime)x.Rows[0][0]);
                    else
                        if (y.Rows.Count != 0 && z.Rows.Count == 0)
                            FromDate = MinDateTime((DateTime)y.Rows[0][0], (DateTime)x.Rows[0][0]);
                        else
                            if (y.Rows.Count == 0 && z.Rows.Count == 0)
                                FromDate = (DateTime)x.Rows[0][0];
                            else FromDate = MinDateTime((DateTime)x.Rows[0][0], (DateTime)y.Rows[0][0], (DateTime)z.Rows[0][0]);
                }
                ToDate = DateTime.Now;   
            }
            public DateTime MinDateTime(DateTime a, DateTime b)
            {
                if (a < b)
                    return a;
                else return b;
            }
            public DateTime MinDateTime(DateTime a, DateTime b, DateTime c)
            {
                DateTime Result = a;
                if (Result > b)
                    Result = b;
                if (Result > c)
                    Result = c;
                return Result;
            }
            public Customer()
            {
                IsTradeLogViewing = false;
                Messenger = new Bussiness.Messenger();
                IsEditable = true;
                CurrentView = new Data.Customer();
                lstCustomer = Data.Customer.GetAllCustomer();
                lstTicketOrder = new ObservableCollection<TicketOrder>();
                lstBookedTicket = new ObservableCollection<BookedTicket>();
                lstMenuOrder = new ObservableCollection<MenuOrder>();
                IsViewModeEnable = true;
                IsCreating = false;
                
                ChooseCustomerCommand = new RelayCommand<Data.Customer>(
                    (s) => true,
                    (s) =>
                    {
                        CurrentViewIndex = lstCustomer.IndexOf(s) + 1;
                        CurrentView = s;
                        IsEditable = false;
                        IsViewModeEnable = false;
                        lstTicketOrder = CurrentView.GetAllTicketOrder();
                        lstBookedTicket = CurrentView.GetAllBookedTicket();
                        lstMenuOrder = CurrentView.GetAllMenuOrder();
                    }
                );
                CreateCommand = new RelayCommand<Data.Customer>(
                    (s) => IsViewModeEnable,
                    (s) =>
                    {
                        CurrentView = new Data.Customer();
                        IsEditable = true;
                        IsViewModeEnable = false;
                        IsCreating = true;
                    }
                );
                SetCustomerCommand = new RelayCommand<Data.Customer>(
                    (s) => true,
                    (s) =>
                    {
                        CurrentView = s;
                        ViewAllCommand.Execute(null);
                        Messenger.Send(new Message.SetCustomerOK());
                    }
                );
                EditCommand = new RelayCommand<Data.Customer>(
                    (s) => !IsEditable&&!IsViewModeEnable,
                    (s) =>
                    {
                        IsEditable = true;
                    }
                );
                SaveCommand = new RelayCommand<Data.Customer>(
                    (s) => true,
                    (s) =>
                {
                    if (lstCustomer.IndexOf(CurrentView) ==-1 ) lstCustomer.Add(CurrentView);
                    if (IsCreating)
                    {
                        CurrentViewIndex = lstCustomer.IndexOf(CurrentView) + 1;
                        IsCreating = false;
                    }
                    CurrentView.Save();
                    IsEditable = false;
                }
                );
                BackCommand = new RelayCommand<Data.Customer>(
                (s) => true,
                (s) =>
                {
                    if (IsEditable)
                    {
                        var message1 = new Message.BackConfimation();
                        Messenger.Send(message1);
                        if (message1.Result == MessageBoxResult.Yes)
                        {
                            Messenger.Send(new Message.BackConfimationOK());
                            IsViewModeEnable = true;
                            IsEditable = true;
                            if (lstCustomer.IndexOf(CurrentView) == -1) return;
                            lstCustomer[CurrentViewIndex - 1] = new Data.Customer(CurrentView.ID);
                            CurrentView = lstCustomer[CurrentViewIndex - 1];
                            
                        }
                    }
                    else
                    {
                        IsViewModeEnable = true;
                        IsEditable = true;
                        Messenger.Send(new Message.BackConfimationOK());
                    }
                }
                );
                DeleteCommand = new RelayCommand<Data.Customer>(
                (s) => !IsViewModeEnable,
                (s) =>
                {
                    try
                    {
                        var message = new Message.DeleteConfirmation();
                        Messenger.Send(message);
                        if (message.Result == MessageBoxResult.No) return;

                        CurrentView.Delete();
                        lstCustomer.Remove(CurrentView);
                        IsViewModeEnable = true;
                        IsEditable = true;
                        Messenger.Send(new Message.BackConfimationOK());
                    }
                    catch
                    {
                        Messenger.Send(new Message.DeleteFailed());
                    }
                }
                );
            
                PreviousCommand = new RelayCommand<Data.Customer>(
                (s) => CurrentViewIndex > 1,
                (s) =>
                {
                    --CurrentViewIndex;
                    lstTicketOrder = CurrentView.GetAllTicketOrder();
                    lstBookedTicket = CurrentView.GetAllBookedTicket();
                    lstMenuOrder = CurrentView.GetAllMenuOrder();
                    LoadDateTime();
                }
            );
                NextCommand = new RelayCommand<Data.Customer>(
                    (s) => CurrentViewIndex < lstCustomer.Count,
                    (s) =>
                    {
                        ++CurrentViewIndex;
                        lstTicketOrder = CurrentView.GetAllTicketOrder();
                        lstBookedTicket = CurrentView.GetAllBookedTicket();
                        lstMenuOrder = CurrentView.GetAllMenuOrder();
                        LoadDateTime();
                    }
                );
                GoToPageCommand = new RelayCommand<Data.Customer>(
                    (s) => true,
                    (s) =>
                    {
                        CurrentViewIndex = CurrentViewIndex;
                        lstTicketOrder = CurrentView.GetAllTicketOrder();
                        lstBookedTicket = CurrentView.GetAllBookedTicket();
                        lstMenuOrder = CurrentView.GetAllMenuOrder();
                        LoadDateTime();
                    }
                );
                SearchFilter = new ObservableCollection<string>();
                SearchFilterIndex = 0;
                SearchCommand = new RelayCommand<String>(
                    (s) => true,
                    (s) =>
                    {
                        if (!IsSearching)
                        {
                            IsSearching = true;
                            return;
                        }
                        switch (SearchFilterIndex)
                        {
                            case 0: lstCustomer = Data.Customer.SearchByName(s);
                                break;
                            case 1: lstCustomer = Data.Customer.SearchByNo(s);
                                break;
                        }
                    }
                ); 
                FilterCommand = new RelayCommand<object>(
                     (s) => true,
                     (s) =>
                     {
                         lstTicketOrder = Data.TicketOrder.Filter(FromDate, ToDate, CurrentView.ID);
                         lstBookedTicket = Data.BookedTicket.Filter(FromDate, ToDate, CurrentView.ID);
                         lstMenuOrder = Data.MenuOrder.Filter(FromDate, ToDate, CurrentView.ID);
                     }
                 ); 
                ViewAllCommand = new RelayCommand<object>(
                (s) => !IsEditable,
                (s) =>
                {
                    lstTicketOrder = CurrentView.GetAllTicketOrder();
                    lstBookedTicket = CurrentView.GetAllBookedTicket();
                    lstMenuOrder = CurrentView.GetAllMenuOrder();
                    LoadDateTime();
                    IsTradeLogViewing = true;
                }
            );
                SearchCancelCommand = new RelayCommand<object>(
                    (s) => true,
                    (s) =>
                    {
                        IsSearching = false;
                        lstCustomer = Data.Customer.GetAllCustomer();
                    }
                );
                BackToFormViewCommand = new RelayCommand<object>(
                    (s) => true,
                    (s) =>
                    {
                        IsTradeLogViewing = false;
                    }
                );
                ResetPasswordCommand = new RelayCommand<object>(
                (s) => !IsEditable && !IsViewModeEnable,
                (s) =>
                {
                    try
                    {
                        var message = new Message.ResetPasswordConfimation();
                        Messenger.Send(message);
                        if (message.Result == MessageBoxResult.No) return;

                        CurrentView.Password = CurrentView.CardNo + "";
                        CurrentView.Save();
                        Messenger.Send(new Message.ResetPasswordOK());
                    }
                    catch
                    {
                        Messenger.Send(new Message.ResetPasswordFailed());
                    }
                }
            ); 
            }    
            public void Save()
            {
                CurrentView.Password = CurrentView.CardNo.ToString();
                CurrentView.Save();
            }
        }
}